package xj.graph2d.command;

import java.awt.geom.Point2D;

import xj.graph2d.GraphDocument;
import xj.graph2d.GraphEdgeBase;
import xj.graph2d.GraphView;
import xj.graph2d.ModelListener;
import xj.graph2d.shapes.GraphEdgeShape;
import xj.graph2d.shapes.OrthogonalLineShape;
import xj.graph2d.shapes.PolyCurveShape;
import xj.graph2d.shapes.PolyShape;
import xj.graph2d.shapes.CurveShapeBase;

public class ChangeEdgeShapeCommand extends AbstractCommand {

  public ChangeEdgeShapeCommand(GraphView view, 
				GraphDocument doc, 
				GraphEdgeShape edge, 
				GraphEdgeBase newShape) {
    super(view, doc);
    this.edge = edge;
    this.newShape = newShape;
    if (edge != null) { 
      this.oldShape = edge.getEdgeShape();
    }
    graph = doc;
  }

  public void execute() {
    doChangeEdgeShape(newShape);
  }

  public void undo() {
    doChangeEdgeShape(oldShape);
  }

  void doChangeEdgeShape(GraphEdgeBase shape) { 
    if (edge != null && shape != null) {
      Point2D p1 = edge.getEnd1();
      Point2D p2 = edge.getEnd2();
      float x1 = (float) p1.getX();
      float y1 = (float) p1.getY();
      float x2 = (float) p2.getX();
      float y2 = (float) p2.getY();
      edge.setEdgeShape(shape); 
      if (shape instanceof PolyShape) {
	PolyShape pline = (PolyShape) shape;
	pline.scaleFirstLast(x1, y1, x2, y2);
	
	if (pline instanceof PolyCurveShape) {
	  PolyCurveShape curve = (PolyCurveShape) pline;
	  curve.adjustControlPoints();
	} else if (pline instanceof OrthogonalLineShape) {
	  OrthogonalLineShape oline = (OrthogonalLineShape) pline;
	  oline.normalizePoints();
	}
      } else if (shape instanceof CurveShapeBase) {
	//edge.setEndsAdj(x1, y1, x2, y2, true);
	edge.setEnds(x1, y1, x2, y2);
	edge.adjustControlPoints();
      } else { 
	edge.setEnds(x1, y1, x2, y2);
      }
      edge.adjustEnds();
      edge.adjustEdge();
      edge.layoutComponents();
      //edge.doLayout();

      ModelListener ml = edge.getModelListener();
      if (ml != null) { 
	ml.updateShape();
      }
      canvas.repaint();
    }
  }

  protected GraphEdgeShape edge;
  protected GraphEdgeBase newShape, oldShape;
  protected GraphDocument graph;

}
